package org.foreningsgatan.mercenaries.level;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import org.foreningsgatan.mercenaries.Configuration;
import org.foreningsgatan.mercenaries.helpers.terrain.VegetationComparator;
import org.foreningsgatan.mercenaries.manual.generator.InterpolatedMapGenerator;
import org.foreningsgatan.mercenaries.manual.generator.ScatterObjects;
import org.foreningsgatan.mercenaries.manual.shared.TerrainTexture;
import org.foreningsgatan.mercenaries.model.GroundDecal;
import org.foreningsgatan.mercenaries.model.LightSource;
import org.foreningsgatan.mercenaries.model.Vegetation;
import org.foreningsgatan.modular.lightsources.CacheType;
import org.foreningsgatan.modular.lightsources.RGB;
import org.foreningsgatan.modular.terrain.model.SimpleMap;

public class RandomLevelLoader implements LevelLoader {
	private static final int sNUMBER_OF_LIGHTS = Configuration.sMapSize;

	private static final int sLIGHT_SIZE = 12;
	
	private static final String[] cTreeKeys = { 
		"frames.vegetation.tree01", 
		"frames.vegetation.tree02", 
		"frames.vegetation.tree03", 
		"frames.vegetation.tree04"
	}; 
	
	private static final String[] cBushKeys = {  
		"frames.vegetation.bush01a",
		"frames.vegetation.bush01b", 
		"frames.vegetation.bush01c"
	};
	
	private SimpleMap mSimpleMap;
	
	private Random mRandom;
	
	public RandomLevelLoader() {
		mRandom = new Random();
	}

	public List<GroundDecal> loadDecals() {
		List<GroundDecal> vDecals = new ArrayList<GroundDecal>();
		
		vDecals.addAll(ScatterObjects.scatterDecal(mSimpleMap, 
				TerrainTexture.GRASS_50_EARTH, 0.025f, "frames.vegetation.largegrass01"));
		vDecals.addAll(ScatterObjects.scatterDecal(mSimpleMap, 
				TerrainTexture.GRASS_75_EARTH, 0.012f, "frames.vegetation.largegrass01"));
		vDecals.addAll(ScatterObjects.scatterDecal(mSimpleMap, 
				TerrainTexture.EARTH, 0.025f, "frames.vegetation.sand01"));
		vDecals.addAll(ScatterObjects.scatterDecal(mSimpleMap, 
				TerrainTexture.GRASS_50_EARTH, 0.025f, "frames.vegetation.moss01"));
		vDecals.addAll(ScatterObjects.scatterDecal(mSimpleMap, 
				TerrainTexture.GRASS_50_EARTH, 0.12f, "frames.vegetation.leaves01"));
		vDecals.addAll(ScatterObjects.scatterDecal(mSimpleMap, 
				TerrainTexture.GRASS_75_EARTH, 0.25f, "frames.vegetation.leaves01"));
		vDecals.addAll(ScatterObjects.scatterDecal(mSimpleMap, 
				TerrainTexture.LEAVES, 0.25f, "frames.vegetation.leaves01"));
		vDecals.addAll(ScatterObjects.scatterDecal(mSimpleMap, 
				TerrainTexture.EARTH, 0.25f, "frames.vegetation.leaves01"));
		
		return vDecals;
	}

	public List<Vegetation> loadVegetation() {
		List<Vegetation> vVegetation = new ArrayList<Vegetation>();
		
		vVegetation.addAll(ScatterObjects.scatter(mSimpleMap, 
				TerrainTexture.GRASS_50_EARTH, 0.25f, true, false, cTreeKeys));
		vVegetation.addAll(ScatterObjects.scatter(mSimpleMap, 
				TerrainTexture.GRASS_75_EARTH, 0.15f, true, false, cTreeKeys));
		vVegetation.addAll(ScatterObjects.scatter(mSimpleMap, 
				TerrainTexture.LEAVES, 0.05f, true, false, cTreeKeys));
		
		vVegetation.addAll(ScatterObjects.scatter(mSimpleMap, 
				TerrainTexture.GRASS_50_EARTH, 1.00f, false, true, "frames.vegetation.grass01"));
		vVegetation.addAll(ScatterObjects.scatter(mSimpleMap, 
				TerrainTexture.GRASS_75_EARTH, 1.00f, false, true, "frames.vegetation.grass01"));
		vVegetation.addAll(ScatterObjects.scatter(mSimpleMap, 
				TerrainTexture.LEAVES, 0.50f, false, true, "frames.vegetation.grass01"));
		vVegetation.addAll(ScatterObjects.scatter(mSimpleMap, 
				TerrainTexture.EARTH, 0.25f, false, true, "frames.vegetation.grass01"));
		
		vVegetation.addAll(ScatterObjects.scatter(mSimpleMap, 
				TerrainTexture.GRASS_50_EARTH, 0.05f, false, true, cBushKeys));
		vVegetation.addAll(ScatterObjects.scatter(mSimpleMap, 
				TerrainTexture.GRASS_75_EARTH, 0.12f, false, true, cBushKeys));
		vVegetation.addAll(ScatterObjects.scatter(mSimpleMap, 
				TerrainTexture.LEAVES, 0.25f, false, true, cBushKeys));
		vVegetation.addAll(ScatterObjects.scatter(mSimpleMap, 
				TerrainTexture.EARTH, 0.12f, false, true, cBushKeys));
		
		Collections.sort(vVegetation, new VegetationComparator());
		
		return vVegetation;
	}

	public SimpleMap loadTerrain() {
		List<TerrainTexture> vTextures = new ArrayList<TerrainTexture>();
		vTextures.add(TerrainTexture.GRASS_50_EARTH);
		vTextures.add(TerrainTexture.GRASS_75_EARTH);
		vTextures.add(TerrainTexture.LEAVES);
		vTextures.add(TerrainTexture.EARTH);
		vTextures.add(TerrainTexture.EARTH_50_ROCKS);
		vTextures.add(TerrainTexture.ROCKS);
		vTextures.add(TerrainTexture.HEXAGONAL_TILES_WORN_50_EARTH);
		vTextures.add(TerrainTexture.HEXAGONAL_TILES_WORN);

		this.mSimpleMap = InterpolatedMapGenerator.generate(Configuration.sMapSize,
				vTextures.toArray());

		return mSimpleMap;
	}

	public List<LightSource> loadLightSources() {
		List<LightSource> vLightSources = new ArrayList<LightSource>();
		
		for (int i = 0; i < sNUMBER_OF_LIGHTS; i++) {
			double x = mRandom.nextDouble() * Configuration.sMapSize;

			double y = mRandom.nextDouble() * Configuration.sMapSize;

			double r = mRandom.nextDouble() * sLIGHT_SIZE + (sLIGHT_SIZE / 2);

			RGB rgb = new RGB(mRandom.nextFloat(), mRandom.nextFloat(), mRandom
					.nextFloat());

			vLightSources.add(new LightSource(x, y, r, rgb,
					CacheType.DYNAMIC_FULL));
		}
		
		return vLightSources;
	}
}
